package com.zhoug.zmui3.chart;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.RectF;
import android.graphics.Xfermode;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.zhoug.common3.utils.LogUtils;
import com.zhoug.common3.utils.MathUtils;
import com.zhoug.zmui3.R;

import java.util.Locale;

import androidx.annotation.Nullable;

/**
 * 仪表盘 图表
 *
 * @Author 35574
 * @Date 2021/1/22
 * @Description
 */
@Deprecated
public class ZMUIDashboardView extends View {
    private static final String TAG = ">>>ZMUIDashboardView";
    private static final boolean DEBUG = false;

    private final int DEF_SIZE;//默认大小

    public static final int TEXT_POSITION_INNER = 0;
    public static final int TEXT_POSITION_OUTER = 1;
    /**
     * 刻度文本的位置:弧形外面,弧形里面
     */
    private int textPosition;
    /**
     * 刻度文本的颜色
     */
    private int textColor;
    /**
     * 刻度文本的大小
     */
    private float textSize;

    /**
     * 弧长的度数 0-360
     */
    private int degrees = 142;
    /**
     * 两边偏移的度数
     */
    private float offsetDegree=1.0f;//开始和结尾偏移的度数

    /**
     * 弧的颜色
     */
    private int arcColor;
    /**
     * 弧的宽度
     */
    private float arcStrokeWidth;


    private float minValue = 0;//最小值
    private float maxValue = 100;//最大值
    private float value;//当前值
    private float oldValue;//
    private int clockPointNum = 31;//刻度数目
    private int drawValueInterval = 3;//每几个刻度画一个ValueLabel,0不画标签
    private int clockPointLength = 20;//刻度的长度
    private int clockPointWidth = 6;//刻度的宽度
    private boolean drawValueIntervalLong=false;//画标签时是否画成长刻度
    private float valueMarginArc=10;//标签和圆弧的间距

    private float mRadius;//半径
    private float mCenterX;
    private float mCenterY;

    private Paint mPaint;
    private TextPaint mTextPaint;
    private ValueFormat valueFormat;

    public ZMUIDashboardView(Context context) {
        this(context, null);
    }

    public ZMUIDashboardView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, R.attr.zmui_style_ZMUIDashboardView);
    }

    public ZMUIDashboardView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        //默认150dp
        DEF_SIZE = (int) (context.getResources().getDisplayMetrics().density * 150 + 0.5);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ZMUIDashboardView, defStyleAttr, R.style.zmui_style_ZMUIDashboardView);
        textPosition = a.getInt(R.styleable.ZMUIDashboardView_zmui_textPosition, TEXT_POSITION_INNER);
        textColor = a.getColor(R.styleable.ZMUIDashboardView_android_textColor, Color.BLACK);
        textSize = a.getDimension(R.styleable.ZMUIDashboardView_android_textSize, 20);

        arcColor = a.getColor(R.styleable.ZMUIDashboardView_zmui_arcColor, Color.BLACK);
        arcStrokeWidth = a.getDimension(R.styleable.ZMUIDashboardView_zmui_arcStrokeWidth, 3);
        degrees = a.getInt(R.styleable.ZMUIDashboardView_zmui_degrees, 180);

        value = a.getFloat(R.styleable.ZMUIDashboardView_zmui_dashboard_value, 0);

        a.recycle();

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setAntiAlias(true);

        mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setAntiAlias(true);

//        setLayerType(LAYER_TYPE_HARDWARE,null);
    }


    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int measureWidth = 0;
        int measureHeight = 0;
        if (DEBUG) {
            LogUtils.d(TAG, "onMeasure:widthSize=" + widthSize + ",heightSize=" + heightSize);
        }
        if (widthMode == MeasureSpec.EXACTLY && heightMode == MeasureSpec.EXACTLY) {
            //宽高确定
            if (DEBUG) {
                LogUtils.d(TAG, "onMeasure:宽高确定");
            }
            measureWidth = widthSize;
            measureHeight = heightSize;
        } else if (widthMode == MeasureSpec.EXACTLY) {
            //宽度确定,高度自适应
            if (DEBUG) {
                LogUtils.d(TAG, "onMeasure:宽度确定,高度自适应");
            }
            measureWidth = widthSize;
            //用宽度计算直径
            int d = measureWidth - getPaddingStart() - getPaddingEnd();
            measureHeight = getPaddingTop() + getPaddingBottom() + d;
            if (heightSize > 0) {
                measureHeight = Math.min(heightSize, measureHeight);
            } else {
                measureHeight = Math.min(DEF_SIZE, measureHeight);
            }
        } else if (heightMode == MeasureSpec.EXACTLY) {
            //高度确定,宽度自适应
            if (DEBUG) {
                LogUtils.d(TAG, "onMeasure:高度确定,宽度自适应");
            }
            measureHeight = heightSize;
            int d = measureHeight - getPaddingTop() - getPaddingBottom();
            measureWidth = getPaddingStart() + getPaddingEnd() + d;
            if (widthSize > 0) {
                measureWidth = Math.min(widthSize, measureWidth);
            } else {
                measureWidth = Math.min(DEF_SIZE, measureWidth);
            }
        } else {
            if (DEBUG) {
                LogUtils.d(TAG, "onMeasure:宽高自适应");
            }
            if (widthSize > 0) {
                measureWidth = Math.min(DEF_SIZE, widthSize);
            } else {
                measureWidth = DEF_SIZE;
            }
            if (heightSize > 0) {
                measureHeight = Math.min(DEF_SIZE, heightSize);
            } else {
                measureHeight = DEF_SIZE;
            }

            int size = Math.min(measureWidth - getPaddingStart() - getPaddingEnd(), measureHeight - getPaddingTop() - getPaddingBottom());
            measureWidth = size;
            measureHeight = size;
        }
        if (DEBUG) {
            LogUtils.d(TAG, "onMeasure:measureWidth=" + measureWidth + ",measureHeight=" + measureHeight);
        }

        //圆形的半径
        float textW = measureClockText() ;
        float textH=textSize;
        //宽度限制的最大半径
        int maxRadius= (int) ((measureWidth-textW*2-valueMarginArc*2-getPaddingStart()-getPaddingEnd())/2);
        if(degrees<180){
            //高度限制的最大半径
            mRadius=measureHeight-(getPaddingTop()+getPaddingBottom()+textH*2+valueMarginArc*2);
        }else{
            //高度限制的最大半径
            float startDegree = getStartDegree();
          mRadius= (float) ((measureHeight-(getPaddingTop()+getPaddingBottom()+textH*2+valueMarginArc*2))/(1+Math.abs(Math.sin(startDegree*Math.PI/180))));
        }
        //取最小值为真实半径
        mRadius=Math.min(maxRadius,mRadius);
        //根据半径重新计算出高度
        measureHeight = (int) ((int) (measureArcHeight(mRadius, degrees)+getPaddingTop()+getPaddingBottom())+textH*2+valueMarginArc*2);
        //画弧度的圆心
        mCenterX = getPaddingStart() + ((measureWidth - getPaddingStart() - getPaddingEnd()) >> 1);
        mCenterY = getPaddingTop() +textH+valueMarginArc+mRadius;

        if (DEBUG) {
            LogUtils.d(TAG, String.format(Locale.CANADA,"mRadius=%s,mCenterX=%s,mCenterY=%s",mRadius,mCenterX,mCenterY));
        }
        setMeasuredDimension(measureWidth, measureHeight);




       /* mRadius = Math.min(measureWidth-textW*2-valueMarginArc*2, measureHeight-textH*2-valueMarginArc*2) / 2;//
        measureHeight = (int) ((int) (measureArcHeight(mRadius, degrees)+getPaddingTop()+getPaddingBottom())+textH*2+valueMarginArc*2);

        mCenterX = getPaddingStart() + ((measureWidth - getPaddingStart() - getPaddingEnd()) >> 1);
        mCenterY = getPaddingTop() +textH+valueMarginArc+mRadius;

        if (DEBUG) {
            LogUtils.d(TAG, String.format(Locale.CANADA,"mRadius=%s,mCenterX=%s,mCenterY=%s",mRadius,mCenterX,mCenterY));
        }
        setMeasuredDimension(measureWidth, measureHeight);*/
    }

    /**
     * 计算弧度的高度
     *
     * @param radius
     * @param degree
     * @return
     */
    private float measureArcHeight(float radius, float degree) {
        if (degree == 0) {
            return 0;
        }
        degree = Math.abs(degree % 360);
        if (degree == 0) {
            return radius * 2;
        } else if (degree <= 180) {
            return radius;
        } else {
            float arcYPoint = MathUtils.getArcYPoint(0, radius, getStartDegree());
            return radius + Math.abs(arcYPoint);
        }
    }

    /**
     * 弧度的开始角度
     *
     * @return
     */
    private float getStartDegree() {
        return 180 + ((180 - degrees) >> 1);
    }

    /**
     * 测量文本尺寸:宽
     */
    private float measureClockText() {
        mTextPaint.setTextSize(textSize);
        ValueFormat valueFormat = getValueFormat();
        String text = valueFormat.getValueFormat(maxValue);
        float w = mTextPaint.measureText(text);
        if (DEBUG) {
            LogUtils.d(TAG, "measureClockText:"+w);
        }
        return w;
    }



    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawArc(canvas);
        drawDividerAndText(canvas);
        drawPointer(canvas);
    }


    private RectF rectF = new RectF();

    /**
     * 画弧
     *
     * @param canvas
     */
    private void drawArc(Canvas canvas) {
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(arcStrokeWidth);
        float ban = arcStrokeWidth / 2;//弧线宽度的一半
        mPaint.setColor(arcColor);
        rectF.left = mCenterX-mRadius+ban;
        rectF.top =mCenterY-mRadius+ban;
        rectF.right =  mCenterX+mRadius-ban;
        rectF.bottom = mCenterY+mRadius-ban;

       float startDegree=getStartDegree();
        canvas.drawArc(rectF, startDegree  , degrees, false, mPaint);

    }

    /**
     * 绘制刻度和数字
     *
     * @param canvas
     */
    private void drawDividerAndText(Canvas canvas) {

        mPaint.setColor(arcColor);
        mPaint.setStrokeWidth(clockPointWidth);
        float r1=mRadius-arcStrokeWidth+1;//刻度线起点坐标所在的圆弧半径
        float r2=mRadius-arcStrokeWidth-clockPointLength;//刻度线终点坐标所在的圆弧半径
        float r2_=mRadius-arcStrokeWidth-clockPointLength*2;//长刻度线终点坐标所在的圆弧半径
        float r3=mRadius+valueMarginArc;//文字开始坐标所在圆弧的半径

        float startDegree = getStartDegree()+offsetDegree;
        float arcDegree;
        float pDegree = (degrees-offsetDegree*2)*1.0f / (clockPointNum-1);
        float pValue=(maxValue-minValue)/(clockPointNum-1);

        mTextPaint.setColor(textColor);
        mTextPaint.setTextSize(textSize);
        int cPosition=(clockPointNum-1)/2;//圆弧上中点的位子
        float startX;
        float startY;
        float endX;
        float endY;
        boolean drawValue=false;
        for(int i=0;i<clockPointNum;i++){
            arcDegree=i*pDegree+startDegree;
            if(drawValueInterval!=0){
                drawValue=i%drawValueInterval==0;
            }
            startX = MathUtils.getArcXPoint(mCenterX, r1, arcDegree);
            startY = MathUtils.getArcYPoint(mCenterY, r1, arcDegree);
            if(drawValue&& drawValueIntervalLong){
                endX = MathUtils.getArcXPoint(mCenterX, r2_, arcDegree);
                endY = MathUtils.getArcYPoint(mCenterY, r2_, arcDegree);
                mPaint.setStrokeWidth(clockPointWidth*2);
            }else{
                endX = MathUtils.getArcXPoint(mCenterX, r2, arcDegree);
                endY = MathUtils.getArcYPoint(mCenterY, r2, arcDegree);
                mPaint.setStrokeWidth(clockPointWidth);
            }
            if (DEBUG) {
                LogUtils.d(TAG, "drawDividerAndText:startX="+startX+",startY="+startY+",endX="+endX+",endY="+endY  );
            }
            canvas.drawLine(startX,startY,endX,endY,mPaint);
            if(drawValue){
                if(i<cPosition){
                    //圆弧左边的文字右对齐
                    mTextPaint.setTextAlign(Paint.Align.RIGHT);
                }else if(i==cPosition){
                    //圆弧中间的文字居中对齐
                    mTextPaint.setTextAlign(Paint.Align.CENTER);
                } else{
                    //圆弧右边的文字左对齐
                    mTextPaint.setTextAlign(Paint.Align.LEFT);
                }

                startX = MathUtils.getArcXPoint(mCenterX, r3, arcDegree);
                startY = MathUtils.getArcYPoint(mCenterY, r3, arcDegree);

                String valueFormat = this.valueFormat.getValueFormat(i * pValue);
                canvas.drawText(valueFormat,startX,startY,mTextPaint);
            }

        }

    }

    private Xfermode CLEAR=new PorterDuffXfermode(PorterDuff.Mode.SRC_IN);
    private Path path=new Path();
    /**
     * 画指针
     * @param canvas
     */
    private void drawPointer(Canvas canvas){
        //偏移的角度
        float offDegree=value / (maxValue - minValue)*degrees;
        float d = offDegree+getStartDegree();
        if (DEBUG) {
            LogUtils.d(TAG, "drawPointer:d="+d);
        }

        float r=mRadius-arcStrokeWidth-clockPointLength*2-50;//刻度线起点坐标所在的圆弧半径
        path.reset();
        path.moveTo(mCenterX-r,mCenterY);
        path.lineTo(mCenterX,mCenterY-30);
        path.lineTo(mCenterX+25,mCenterY-5);
        path.lineTo(mCenterX+25,mCenterY+5);
        path.lineTo(mCenterX,mCenterY+30);
        path.close();

        canvas.save();
        float rotate=offDegree+ ((180 - degrees) >> 1);
        canvas.rotate(rotate,mCenterX,mCenterY);

        mPaint.setStrokeWidth(1);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setColor(arcColor);
        canvas.drawPath(path,mPaint);
        Xfermode xfermode = mPaint.getXfermode();
        mPaint.setXfermode(CLEAR);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(6);
        Drawable background = getBackground();
        if(background instanceof ColorDrawable){
            mPaint.setColor(((ColorDrawable) background).getColor());
        }else{
            mPaint.setColor(Color.TRANSPARENT);
        }
        canvas.drawCircle(mCenterX,mCenterY,10,mPaint);
        mPaint.setXfermode(xfermode);
        canvas.restore();
    }

    public void setValue(float value) {
        this.oldValue=this.value;
        this.value = value;
    }

    public float getValue() {
        return value;
    }

    public void setMinValue(float minValue) {
        this.minValue = minValue;
    }

    public void setMaxValue(float maxValue) {
        this.maxValue = maxValue;
    }



    public void startAnim( ){
        int during =  ((int)(Math.abs(oldValue - value) / 360 * 5000));
        if (DEBUG) {
            LogUtils.d(TAG, "startAnim:during="+during);
        }
        if(during<200){
            during=200;
        }
        ValueAnimator anim = ValueAnimator.ofFloat(oldValue, value);
        anim.setDuration(during);
        anim.setInterpolator(new LinearInterpolator());
        anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                value = (float) animation.getAnimatedValue();
                if (DEBUG) {
                    LogUtils.d(TAG, "onAnimationUpdate:value=" + value);
                }
                postInvalidate();
            }
        });
        anim.start();
    }

    public void setDegrees(int degrees) {
        this.degrees = degrees;
        requestLayout();
    }

    public ValueFormat getValueFormat() {
        if(valueFormat==null){
            valueFormat=new DefaultValueFormat();
        }
        return valueFormat;
    }

    public void setValueFormat(ValueFormat valueFormat) {
        this.valueFormat = valueFormat;
    }

    public interface ValueFormat{
        String getValueFormat(float value);
    }


    public static class  DefaultValueFormat implements ValueFormat{

        @Override
        public String getValueFormat(float value) {
//            return Float.toString(value);
            int a= (int) value;
            return a+"%";
        }
    }



}
